package com.powernode.listener;

import cn.hutool.core.date.DateUnit;
import com.powernode.constant.RabbitMQConstant;
import com.powernode.dto.ProductDto;
import com.powernode.entity.Order;
import com.powernode.entity.OrderItem;
import com.powernode.enums.OrderStatus;
import com.powernode.exception.BizException;
import com.powernode.feign.PMSFeign;
import com.powernode.service.OrderService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * 订单消息监听器
 */
@Slf4j
@Component
public class MQListener {
    @Autowired
    private OrderService orderService;
    @Autowired
    private PMSFeign feign;

    /**
     * 取消订单，设置为延迟发送，当订单超过有效期后，消息队列向消费端发送消息
     */
    @Transactional
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = RabbitMQConstant.QUEUE_DELAY),
            exchange = @Exchange(name = RabbitMQConstant.EXCHANGE_DELAY,delayed = "true"),
            key = RabbitMQConstant.ROUTING_KEY_CANCEL_ORDER
    ))
    public void cancelOrder(Long orderId, Channel channel, Message message){
        try {
            Order order = orderService.getById(orderId);
            if (order != null) {
                // 判断订单处于未付款状态
                if (order.getStatus().equals(OrderStatus.STATUS_1.getCode())){
                    // 取消订单
                    order.setStatus(OrderStatus.STATUS_4.getCode());
                    // 数据库中更新订单状态
                    orderService.updateById(order);
                    //  返回库存
                    List<OrderItem> orderItemList = order.getOrderItems();
                    orderItemList.forEach(item -> {
                        // 根据商品id获取商品
                        ProductDto productDto = feign.getProductById(item.getProductId()).getData();
                        // 设置库存为扣减之前的库存
                        productDto.setStock(productDto.getStock() + item.getNum());
                        // 调用远程接口更新商品
                        feign.edit(productDto);
                    });
                    log.info("取消订单成功，{}",orderId);
                }
            }
            log.info("订单处理完成，{}",orderId);
            // 消息处理成功，手动返回ack
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
            try {
                channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,false);
                log.error("订单异常：{}",orderId);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
